feat(scanner): add inline suppression annotations (# ai-bom: ignore)#79
feat(scanner): add inline suppression annotations (# ai-bom: ignore)#79Automation-Dude wants to merge 1 commit intoTrusera:mainfrom
Conversation
Add two comment-based suppression directives to CodeScanner that let
developers mark intentional AI SDK usage, preventing false positives
without having to exclude entire directories via .ai-bomignore.
New annotations
---------------
# ai-bom: ignore place at end of any line; suppresses SDK
component detection on that line only.
# ai-bom: ignore-file place anywhere in the first 5 lines of a file;
suppresses SDK component detection for the
entire file.
Scope of suppression (deliberate design decision)
--------------------------------------------------
Suppression applies ONLY to SDK/component detection (shadow AI, import
patterns, usage patterns). Hardcoded API key detection is unconditional
and fires regardless of any annotation.
Why this boundary?
Our first instinct was to suppress everything on an annotated line -- if
a developer says 'ignore this', ignore everything. We challenged that
thinking: a hardcoded credential leak is a security finding, not a
false positive. A developer tagging an import as intentional should not
inadvertently silence a leaked key sitting on the same line. The two
concerns are categorically different:
- SDK detection: 'Is this library present?' Can be intentional and
already reviewed. False positives here are routine.
- Hardcoded key: 'Is there a live credential in source?' Cannot be
intentional in any safe codebase. False positives here are rare
and the cost of a missed true positive is severe.
Suppressing shadow AI detection does not break the security intent of
the tool. Suppressing credential detection would.
This mirrors how comparable tools handle the same tension:
- bandit's #nosec suppresses rule violations but the project README
explicitly warns against suppressing credential rules
- detect-secrets has a separate allow-list mechanism specifically
to prevent inline suppression of secrets
- semgrep's nosemgrep follows the same pattern
Idiomatic precedent
-------------------
The annotation pattern follows established Python ecosystem conventions:
flake8 / ruff -> # noqa
mypy -> # type: ignore
bandit -> # nosec
Use cases
---------
- Tool self-scans: pattern definition files contain SDK names as
string literals (e.g. ai-bom's own detectors/ directory). These
are the detection engine, not live SDK usage.
- Test harnesses that import AI SDKs to test detection behavior.
- Compatibility shim code that references SDK names for feature
detection without loading them at runtime.
- Documentation generators that embed SDK names as examples.
Tests added (8 new cases in TestInlineSuppression)
---------------------------------------------------
- Line-level suppression suppresses SDK detection
- Line-level suppression does NOT suppress hardcoded API key
- File-level suppression does NOT suppress hardcoded API key
- Suppressed lines do not affect other lines in the same file
- File-level suppression skips all SDK detection in the file
- File-level annotation honoured on lines 2-5, not only line 1
- File-level annotation after line 5 has no effect
- Files without any annotation are unaffected
|
Thanks for this contribution, Jordan — the feature motivation and security reasoning are solid, and the test coverage is thorough. Before we can merge, a few things need to be addressed: 1. Substring check creates a false-negative bypass (must fix)The current implementation uses: if suppress_sdk_file or "# ai-bom: ignore" in line:Because Please use anchored regex matching instead: import re
_INLINE_IGNORE_RE = re.compile(r"#\s*ai-bom:\s*ignore\b(?!-file)")
_FILE_IGNORE_RE = re.compile(r"#\s*ai-bom:\s*ignore-file\b")Compile these at module level and use 2. No CI checks ran on this branch (must fix)
3. Suppression logic is duplicated across two scan loops (should fix)The same suppression block is added to both 4. Documentation needs updating
Happy to review a v2 once these are addressed — the core logic and test quality are in good shape. 🙏 |
Summary
Add two comment-based suppression directives to \CodeScanner\ that let
developers mark intentional AI SDK usage, preventing false positives without
having to exclude entire directories via .ai-bomignore.
\\python
import openai # ai-bom: ignore <- suppresses SDK detection on this line
ai-bom: ignore-file <- place in first 5 lines; suppresses
import openai # SDK detection for the entire file
\\
The problem this solves
.ai-bomignore\ handles path-level suppression well, but it is too coarse when
only a handful of lines in a file are the source of false positives. The most
common case: a project's own detection engine contains AI SDK names as string
literals (regex patterns, config data) -- not as live runtime dependencies.
Scanning ai-bom itself with ai-bom demonstrates this: 162 components are
reported, all false positives from the pattern definition files.
Design decision: API key detection is unconditional
Our initial implementation suppressed all detection on an annotated line,
including hardcoded API key findings. We reconsidered this.
The two detection types are categorically different:
Suppressing shadow AI detection does not break the security intent of the tool.
Suppressing credential detection would. A developer tagging an import as
intentional should not inadvertently silence a leaked key on the same line.
This is consistent with how comparable tools handle the same tension:
Result: # ai-bom: ignore\ and # ai-bom: ignore-file\ suppress SDK/component
detection only. \hardcoded_api_key\ findings always fire.
Idiomatic precedent
Annotations
Use cases
Quality gates
All three gates pass on Python 3.10-3.13:
\
ruff check src/ tests/ -- 0 errors
mypy src/ai_bom/ -- 0 errors
pytest -v -- 806 passed, 21 skipped
\\
Tests added (8 new cases in \TestInlineSuppression)